Skip to content

Make percentage string values as floats/ints in InfluxDB#7879

Merged
pvizeli merged 4 commits into
home-assistant:devfrom
philhawthorne:influxdb-percents-float
Jun 13, 2017
Merged

Make percentage string values as floats/ints in InfluxDB#7879
pvizeli merged 4 commits into
home-assistant:devfrom
philhawthorne:influxdb-percents-float

Conversation

@philhawthorne
Copy link
Copy Markdown
Contributor

@philhawthorne philhawthorne commented Jun 3, 2017

Description:

Currently Z-wave and other components report an attributes battery
level as an integer, for example

{
"is_awake": false,
"battery_level": 61,
}

However, some other components like Vera add the battery level as a
string

{
"Vera Device Id": 25,
"device_armed": "False",
"battery_level": "63%",
"device_tripped": "False",
}

By removing any % signs in the field, this will send the value to
InfluxDB as an int, which can then be used to plot the data in graphs
correctly, like other percentage fields.

This PR will detect when a percentage is being cast as a string, and remove
the % sign before it is shipped over to InfluxDB.

Not really a Python dev, so if there's a better way to do this, or some tests I
need to add any help would be appreciated.

Checklist:

If user exposed functionality or configuration variables are added/changed:

If the code communicates with devices, web services, or third-party tools:

  • Local tests with tox run successfully. Your PR cannot be merged unless tests pass
  • New dependencies have been added to the REQUIREMENTS variable (example).
  • New dependencies are only imported inside functions that use them (example).
  • New dependencies have been added to requirements_all.txt by running script/gen_requirements_all.py.
  • New files were added to .coveragerc.

If the code does not interact with devices:

  • Local tests with tox run successfully. Your PR cannot be merged unless tests pass
  • Tests have been added to verify that the new code works.

Currently Z-wave and other compontents report an attributes battery
level as an integer, for example

```yaml
{
"is_awake": false,
"battery_level": 61,
}
```

However, some other components like Vera add the battery level as a
string

```yaml
{
"Vera Device Id": 25,
"device_armed": "False",
"battery_level": "63%",
"device_tripped": "False",
}
```

By removing any % signs in the field, this will send the value to
InfluxDB as an int, which can then be used to plot the data in graphs
correctly, like other percentage fields.
@mention-bot
Copy link
Copy Markdown

@philhawthorne, thanks for your PR! By analyzing the history of the files in this pull request, we identified @fabaff, @balloob and @titilambert to be potential reviewers.

@lwis
Copy link
Copy Markdown
Member

lwis commented Jun 3, 2017

There's a test for InfluxDB, could you update that also, please?

@MartinHjelmare
Copy link
Copy Markdown
Member

Is it the correct approach to do this parsing in Influxdb? Maybe each component or base component should make sure not to include units in the values reported?

@lwis
Copy link
Copy Markdown
Member

lwis commented Jun 3, 2017

That only really works for state and unit_of_measurement. But yes, I agree that attributes should not contain units - but there's currently no uniform way to store units for attributes.

Would be good to have something like a dict with a unit, however this would be quite a big change as attributes are just key with simple value at the moment.

@MartinHjelmare
Copy link
Copy Markdown
Member

MartinHjelmare commented Jun 3, 2017

Yes, it wouldn't be a quick fix.

If we add the fix here, can we make it broader somehow, to not only target %? Maybe:

  • Strip all non alfanumeric characters.
  • Check if only numeric characters remain.
  • If so: return those (including decimal point), if not: return the original

@philhawthorne
Copy link
Copy Markdown
Contributor Author

@MartinHjelmare

I thought about that. I was worried this would happen

{
"friendly_name": "Living Lamp 1"
},
{
"friendly_name": "Moto 2X9P"
}

Would just become

{
"friendly_name": 1
},
{
"friendly_name": 29
}

I guess we could keep storing the _str version as well.

{
"friendly_name": 29,
"friendly_name_str": "Moto 2X9P"
}

But not sure if adding so many extra keys would be a good idea?

@lwis
Copy link
Copy Markdown
Member

lwis commented Jun 3, 2017

@philhawthorne I think we should only strip trailing characters, and also store the original string 👍

@philhawthorne
Copy link
Copy Markdown
Contributor Author

@lwis yep that makes sense! I'll make the changes and update the tests to check for it as well

Adds tests and now removes all trailing non-numeric characters for
better use
@philhawthorne
Copy link
Copy Markdown
Contributor Author

Added tests and now removes all trailing non-digits from the attribute.

For example

{
"battery_level": "44%",
"friendly_name": "Johns iPhone 2"
}

Will become

{
"battery_level_str": "44%",
"battery_level": 44,
"friendly_name_str": "Johns iPhone 2"
}

Comment thread homeassistant/components/influxdb.py Outdated
]

percent_remove_regex = re.compile(r"^([0-9.])+\%$")
percent_remove_regex = re.compile(r'[\d.]+')
Copy link
Copy Markdown
Member

@MartinHjelmare MartinHjelmare Jun 5, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should call this something else now, right? non_digit_tail?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct! Cheers. Have updated that

Updates the variable used for the regex to remove trailing non digits
@lwis
Copy link
Copy Markdown
Member

lwis commented Jun 7, 2017

I'm happy with this now, it seems like a sensible change. @MartinHjelmare do you have anything else, or can this be merged?

@MartinHjelmare
Copy link
Copy Markdown
Member

If the regex works I'm happy. There's a small lint error that needs fixing before we can merge.

Copy link
Copy Markdown
Member

@pvizeli pvizeli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

think it is fine to cast the type for influxdb. But we should also fix the Vera component/platform. The state should not be include any types, that is a bug of device and need to be fix.

In this case, remove the *_str. That should be the same as the casted type. All other is a bug that need fix on right position and not inside influxdb. But with this new cast it will make that component more robust.

Fixes a small linting error on the InfluxDB component
@philhawthorne
Copy link
Copy Markdown
Contributor Author

@pvizeli should we update the Vera plugin in this Pull Request? This PR will cover all components that may have this problem.

Wondering if it would be better to separate the Vera updates into a different PR as it may be a breaking change?

@pvizeli
Copy link
Copy Markdown
Member

pvizeli commented Jun 13, 2017

Yes, the fix on other component/platform should be done in a new PR. I see that the *_str are not a part of this PR. I think we should be able now to remove this *_str in a new PR after we merge it. With this change we need not do that anymore.

@pvizeli pvizeli merged commit 1ddcab5 into home-assistant:dev Jun 13, 2017
@balloob balloob mentioned this pull request Jun 16, 2017
@diplix
Copy link
Copy Markdown
Contributor

diplix commented Jun 18, 2017

this change produces many new error for entities that have IP-addresses as attribute, because the regex does not consider strings with more than one dot as not convertible to floats. it seems to just tries to convert everything with a dot in it to a float.

ERROR:homeassistant.core:Error doing job: Future exception was never retrieved
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/homeassistant/components/influxdb.py", line 164, in influx_event_listener
    json_body[0]['fields'][key] = float(value)
ValueError: could not convert string to float: '192.168.1.69'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/concurrent/futures/thread.py", line 55, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/homeassistant/components/influxdb.py", line 170, in influx_event_listener
    non_decimal.sub('', value))
ValueError: could not convert string to float: '192.168.1.69'

@home-assistant home-assistant locked and limited conversation to collaborators Oct 20, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants